#include <glib.h>

static void test_open_close_dir(const gchar *path)
{
    GDir *dir = NULL;
    GError *error = NULL;

    dir = g_dir_open(path, 0, &error);
    if(NULL != dir) {
        g_dir_close(dir);
    } else {
        g_print("stdout: cannot open dir \n");
        g_printerr("stderr: cannot open dir: %s \n", error->message);
    }
}

void test_func_open_close_dir(void)
{
    test_open_close_dir("/aabbcc");
}

void test_func_trap_assert_passed(gconstpointer user_data)
{
    if(g_test_subprocess()) {

        g_assert(NULL != user_data);

        return;
    }

    g_test_trap_subprocess(NULL, 0, 0);
    g_test_trap_assert_passed();
}

void test_func_trap_assert_failed(gconstpointer user_data)
{
    if(g_test_subprocess()) {
        g_assert(NULL != user_data);
        return;
    }

    g_test_trap_subprocess(NULL, 0, 0);
    g_test_trap_assert_failed();
}

void test_func_trap_assert_stdout(gconstpointer user_data)
{
    if(g_test_subprocess()) {
        test_open_close_dir((gchar *)user_data);
        return;
    }

    g_test_trap_subprocess(NULL, 0, 0);
    g_test_trap_assert_stdout("*stdout: cannot open*");
}

void test_func_trap_assert_stderr(gconstpointer user_data)
{
    if(g_test_subprocess()) {
        test_open_close_dir((gchar *)user_data);
        return;
    }

    g_test_trap_subprocess(NULL, 0, 0);
    g_test_trap_assert_stderr("*stderr: cannot open*");
}

void test_func_trap_reached_timeout(gconstpointer user_data)
{
    if(g_test_subprocess()) {
        g_usleep(2000000);
        return;
    }

    g_test_trap_subprocess(NULL, GPOINTER_TO_INT(user_data), 0);

    if(GPOINTER_TO_INT(user_data) > 2000000) {
        // not timeout, subprocess return success
        g_assert_false(g_test_trap_reached_timeout());
    } else {
        // subprocess timeout
        g_assert_true(g_test_trap_reached_timeout());
    }
}

void test_func_trap_has_passed(void)
{
    g_test_trap_subprocess("/test/base/openclosedir", 0, 0);
    g_assert(g_test_trap_has_passed());
}

int main(int argc, char **argv)
{
    g_test_init(&argc, &argv, NULL);

    g_test_add_func("/test/base/openclosedir", test_func_open_close_dir);
    g_test_add_data_func("/test/trap/assert_passed", (gconstpointer)"/home", test_func_trap_assert_passed);
    g_test_add_data_func("/test/trap/assert_failed", NULL, test_func_trap_assert_failed);
    g_test_add_data_func("/test/trap/assert_stdout", (gconstpointer)"/aabbcc", test_func_trap_assert_stdout);
    g_test_add_data_func("/test/trap/assert_stderr", (gconstpointer)"/aabbcc", test_func_trap_assert_stderr);
    g_test_add_data_func("/test/trap/timeout1", GINT_TO_POINTER(1000000), test_func_trap_reached_timeout);
    g_test_add_data_func("/test/trap/timeout2", GINT_TO_POINTER(3000000), test_func_trap_reached_timeout);
    g_test_add_func("/test/trap/haspassed", test_func_trap_has_passed);

    return g_test_run();
}
